require "Cocos2d"
require "Cocos2dConstants"


UIInfo = class("UIInfo")



function UIInfo.create()
    local uiinfo = UIInfo.new()
    uiinfo:init()
    return uiinfo
end

function UIInfo:init()
    self.position = cc.p(0,0)
    self.rotation = 0
    self.scaleX = 1
    self.scaleY = 1
    self.zorder = 0
    self.anchorPt = cc.p(0.5,0.5)
end

function UIInfo:readInfoFromNode(node)
    assert(node ~= nil,"node==nil")
    self.position.x, self.position.y = node:getPosition()
    
    -- local parent = node:getParent()
    -- if parent ~= nil then
    -- 	local ac = parent:getAnchorPoint()
    -- 	local offsetx = parent:getContentSize().width * ac.x
    -- 	local offsety = parent:getContentSize().height * ac.y
    	
    -- 	self.position.x = self.position.x - offsetx
    -- 	self.position.y = self.position.y - offsety
    -- end
        
    self.rotation = node:getRotation()
    self.scaleX = node:getScaleX()
    self.scaleY = node:getScaleY()
    self.zorder = node:getLocalZOrder()
    self.anchorPt = node:getAnchorPoint()
end

function UIInfo:setInfoToNode(node)
	assert(node, "node==nil")
    node:setPosition(self.position.x, self.position.y)
    node:setAnchorPoint(self.anchorPt.x, self.anchorPt.y)
	node:setRotation(self.rotation)
	node:setScale(self.scaleX, self.scaleY)
	node:setLocalZOrder(self.zorder)
end

UIInfo.inst = UIInfo.create()   --new出来，做临时变量使用
------------------------------------------------------------------

uiBMFont = uiBMFont or {}

function uiBMFont:setAddInfo(parent, zorder)
    self.parent = parent
    self.zorder = zorder
end

function uiBMFont:setColor(color3b)
    self.color = color3b
end

function uiBMFont:createMultiLines( text, font, scale, maxWidth, x, y, h)
    -- body
    local mutlilines = zLua_divBMFontToMultiLines(text, font, scale, maxWidth)
    local lines = {}
    for k,v in ipairs(mutlilines)do
        local line = cc.LabelBMFont:create(v, font)
        line:setPosition(x, y - h*(k - 1))
        line:setLocalZOrder(self.zorder)
        line:setScale(scale)
        line:setColor(self.color)
        line:setAnchorPoint(0,0.5)
        self.parent:addChild(line) 
        lines[#lines+1] = line
    end    
    return lines
end


------------------------------------------------------------------

uiEffect = uiEffect or {}

function uiEffect.bounceIn(ui)
    ui:setOpacity(0)
    local fadein = cc.FadeIn:create(0.3)
    ui:setScale(0.8)
    local scale = cc.EaseElasticOut:create(cc.ScaleTo:create(1,1))
    ui:runAction(cc.Spawn:create(fadein, scale))
end
 
function uiEffect.bounceOut(ui, bRemove)
    local fadeout = cc.FadeOut:create(0.25)
    local scale = cc.EaseIn:create(cc.ScaleTo:create(0.25,0.9),4)
    local effect = cc.Spawn:create(fadeout, scale)
    if not bRemove then
        ui:runAction(effect)
    else 
        ui:runAction(cc.Sequence:create(
            effect,
            cc.RemoveSelf:create()
            ))
    end
end

function uiEffect.FadeOut(ui, dur, bRemove, visible)
    local fadeout = cc.FadeOut:create(dur)
    if not bRemove then
        if visible then
            local function vsb()
                ui:setVisible(false)
            end
            ui:runAction(cc.Sequence:create(
                fadeout,
                cc.CallFunc:create(vsb)
                ))
        else
            ui:runAction(fadeout)
        end
        
    else
        ui:runAction(cc.Sequence:create(
            fadeout,
            cc.RemoveSelf:create()
            ))
    end
end

--mask effect
function uiEffect.maskOut(mask)
    uiEffect.FadeOut(mask, 0.2, false, true)
end
function uiEffect.maskIn(mask)
    uiEffect.FadeIn(mask, 0.2)
end


function uiEffect.FadeIn(ui, dur)
    ui:setVisible(true)
    ui:setOpacity(0)
    local fadein = cc.FadeIn:create(dur)
    ui:runAction(fadein)
end

function uiEffect.boom(ui)
     local action = cc.Spawn:create(
            cc.ScaleBy:create(0.4, 6),
            cc.FadeOut:create(0.4)
        )
    ui:runAction(
        cc.Sequence:create(
            action
            ,cc.RemoveSelf:create()
        )
    )
end

function uiEffect.jelly(ui)
    local originScale = (ui:getScaleX()+ui:getScaleY())*0.5
    local actionBy = cc.EaseInOut:create(cc.ScaleTo:create(0.8, 0.98*originScale, 1.02*originScale), 1.8)
    local actionBy2 = cc.EaseInOut:create(cc.ScaleTo:create(0.8, 1.02*originScale, 0.98*originScale), 1.8)
    ui:runAction(cc.RepeatForever:create(
        cc.Sequence:create(actionBy, actionBy2)
    ))
end

function uiEffect.elastic(ui)
    local originScale = (ui:getScaleX()+ui:getScaleY())*0.5
    local actionBy = cc.EaseInOut:create(cc.ScaleTo:create(0.8, 0.95*originScale), 1.8)
    local actionBy2 = cc.EaseInOut:create(cc.ScaleTo:create(0.8, 1.05*originScale), 1.8)
    ui:runAction(cc.RepeatForever:create(
        cc.Sequence:create(actionBy, actionBy2)
    ))
end

function uiEffect.scaleInUp(ui, disty)
    ui:setOpacity(0)
    local a = cc.Sequence:create(
            cc.FadeIn:create(0.3),
            cc.DelayTime:create(0.5),
            cc.FadeOut:create(0.3)
        )
    ui:setScale(0.7)
    local b = cc.Spawn:create(
            cc.ScaleBy:create(0.2, 1.3),
            a,
            cc.MoveBy:create(1.1, cc.p(0, disty))
        )
    ui:runAction(
        cc.Sequence:create(
            b,
            cc.RemoveSelf:create()
        )
    )
end

function uiEffect.MoveIn(ui, from, to)
    ui:setOpacity(0)
    local fadein = cc.FadeIn:create(0.3)
    ui:setPosition(from.x, from.y)
    local move = cc.EaseElasticOut:create(cc.MoveTo:create(1.2, to))
    ui:runAction(cc.Spawn:create(fadein, move))
end

function uiEffect.MoveOut(ui, from, to, bRemove)
    local fadeout = cc.FadeOut:create(0.4)
    ui:setPosition(from.x, from.y)
    local move = cc.EaseIn:create(cc.MoveTo:create(0.9, to), 8)        
    local action = cc.Spawn:create(cc.Sequence:create(cc.DelayTime:create(0.6),fadeout),
                                    cc.Sequence:create(cc.DelayTime:create(0),move) 
                                    ) 
    if not bRemove then 
        ui:runAction(action) 
    else
        ui:runAction(
                        cc.Sequence:create(
                            action,
                            cc.RemoveSelf:create()
                        )
                    )
    end
end

function uiEffect.blink(ui, interval)
    local itv = interval or 0.4
    local Fade_dark = cc.FadeTo:create(itv, 80)
    local Fade_light = cc.FadeTo:create(itv, 255)
    local seq = cc.Sequence:create(Fade_light, cc.DelayTime:create(itv), Fade_dark)
    ui:runAction(cc.RepeatForever:create(seq))
end

----------------------------------------------------
--function uiEffect:addMaskBg(baseView)
--    if self.mask == nil then
--        local cs = pp.visibleSize
--        self.mask = cc.LayerColor:create(cc.c4b(0,0,0,190),cs.width, cs.height)
--        self.mask:setLocalZOrder(pp.z_g_mask)
--        self.mask:setTouchEnabled(true)
--        baseView:addChild(self.mask)
--        self.mask:setVisible(true)
----        self.mask:setOpacity(0)
----        self.mask:runAction(cc.TintTo:create(0.3, 255,255,255))
--        
--        local function onTouchBegan(touch,event)
--            d_print("touch mask")
--            return false
--        end
--        local function onTouchEnded(touch, event)
--            d_print("touch mask ended")
--            local location = touch:getLocation()
--        end
--
--        local listener = cc.EventListenerTouchOneByOne:create()
--        listener:setSwallowTouches(true)
--        listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN )
--        listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED )
--        local eventDispatcher = self.mask:getEventDispatcher()
--        eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self.mask)
--    end
--end
--
--function uiEffect:removeMaskBg()
--    if self.mask then
--        self.mask:removeFromParent(true)
--        self.mask = nil
--    end
--end

--------------------------------------------------------
uiAnimation = uiAnimation or {}

function uiAnimation.load(name, outname, interval, frameCnt, startFrameIdx)
    local animation = cc.Animation:create()
    for i = startFrameIdx, startFrameIdx + frameCnt - 1 do
        local pattern = name.."%02d.png"
        local str = string.format(pattern, i)
--        local sfCache = cc.SpriteFrameCache:getInstance()
--        local sf = sfCache:getSpriteFrameByName(str)
--        assert(sf, "uiAnimation.load nil")

        --animation:addSpriteFrame(sf:getSpriteFrameByName(str))
        animation:addSpriteFrameWithFile(str)
    end
    animation:setDelayPerUnit(interval)
    animation:setRestoreOriginalFrame(false)

    local aniCache = cc.AnimationCache:getInstance()
    aniCache:addAnimation(animation, outname)
end

function uiAnimation.create(name, bRepeated)
    local aniCache = cc.AnimationCache:getInstance()
    local animation = aniCache:getAnimation(name)
    local animate = cc.Animate:create(animation)

    local ani = animate
    if bRepeated and bRepeated == true then
        ani = cc.RepeatForever:create(animate)
    end

    local s = cc.Sprite:create()
    s:runAction(ani)
    return s
end

function uiAnimation.createAutoRelease( name, bRepeated, dur )
    -- body
    local s = uiAnimation.create(name, bRepeated)
    assert(s, "uiAnimation.createAutoRelease s == nil")
    s:runAction(cc.Sequence:create(
                cc.DelayTime:create(dur),
                cc.FadeOut:create(0.2),
                cc.RemoveSelf:create()
                ))
    return s
end


----------------------------------------------------
uiUtil = uiUtil or {}

function uiUtil.createBMFontByHolder(parent, holdername, fntname)
    local holder = parent:getChildByName(holdername)
    UIInfo.inst:readInfoFromNode(holder)
    bmfnt = cc.LabelBMFont:create("", fntname)
    UIInfo.inst:setInfoToNode(bmfnt)

    local parent = holder:getParent()
    parent:addChild(bmfnt)
    holder:removeFromParent(true)
    return bmfnt
end


----------------------------------------------------
uiIndicator = uiIndicator or {}

function uiIndicator:reset() --when scene changing
    self.inst = nil
end

function uiIndicator:create(bUp)
    if self.inst then
        self.inst:removeFromParent(true)
    end
    self.inst = ccui.ImageView:create("common/srcres/shou.png")
    local up = cc.EaseInOut:create(cc.MoveBy:create(0.4, cc.p(0,20)), 1.8)
    local down = cc.EaseInOut:create(cc.MoveBy:create(0.4, cc.p(0,-20)), 1.8)
    local seq
    if bUp then
        seq = cc.Sequence:create(down,up)
    else
        self.inst:setFlippedY(true)
        seq = cc.Sequence:create(up,down)
    end
    self.inst:setScale(0.9)
    self.inst:setOpacity(0)
    self.inst:runAction(cc.FadeIn:create(0.3))        
    self.inst:runAction(cc.RepeatForever:create(seq))
    return self.inst
end

function uiIndicator:remove()
    if self.inst then
        self.inst:runAction(cc.Sequence:create(
            cc.FadeOut:create(0.3),
            cc.RemoveSelf:create()
            ))
        self.inst = nil
    end
end

----------------------------------------------------
uiIndicator2 = uiIndicator2 or {}

function uiIndicator2:reset() --when scene changing
    self.inst = nil
end

function uiIndicator2:create(degree)
    if self.inst then
        self.inst:removeFromParent(true)
    end
    self.inst = ccui.ImageView:create("common/srcres/shou.png")
    self.inst:setRotation(degree)
    local up = cc.EaseInOut:create(cc.ScaleTo:create(0.4, 0.9), 1.8)
    local down = cc.EaseInOut:create(cc.ScaleTo:create(0.4, 1.0), 1.8)
    seq = cc.Sequence:create(up,down)
    
    self.inst:setScale(0.9)
    self.inst:setOpacity(0)
    self.inst:runAction(cc.FadeIn:create(0.3))        
    self.inst:runAction(cc.RepeatForever:create(seq))
    return self.inst
end

function uiIndicator2:remove()
    if self.inst then
        self.inst:runAction(cc.Sequence:create(
            cc.FadeOut:create(0.3),
            cc.RemoveSelf:create()
            ))
        self.inst = nil
    end
end



----------------------------------------------------
baseScene = class("baseScene")

function baseScene:ctor()
    self.base_popWinStack = {}
    self.base_mask = nil
end

function baseScene:base_onOpenWin(win)
    self.base_popWinStack[#self.base_popWinStack+1] = win
    if #self.base_popWinStack == 1 then
        uiEffect.maskIn(self.base_mask)
    end
    local zorder
    if type(win) == "userdata" then
        zorder = win:getLocalZOrder()
    else
        zorder = win.view:getLocalZOrder()
    end
    self.base_mask:setLocalZOrder(zorder - 1)
end

function baseScene:base_onCloseWin(win)
    -- self.base_popWinStack[#self.base_popWinStack] = nil
    for k,v in ipairs(self.base_popWinStack)do
        if v == win then
            table.remove(self.base_popWinStack, k)
        end
    end
    if #self.base_popWinStack == 0 then
        uiEffect.maskOut(self.base_mask)
    else
        local topwin = self.base_popWinStack[#self.base_popWinStack]
        local zorder
        if type(topwin) == "userdata" then              --view
            zorder = topwin:getLocalZOrder()
        else                                            --wrapped "panel"
            zorder = topwin.view:getLocalZOrder()
        end
        self.base_mask:setLocalZOrder(zorder - 1)
    end
end

function baseScene:base_isWinOpened(winname)
    for k,v in ipairs(self.base_popWinStack)do
        if v.class and v.class.__cname == winname then
            return v
        end
    end
    return nil
end

------------------------------------------------------

uiPopNotify = uiPopNotify or {}
function uiPopNotify:reset()
    self.notifypanel = nil
end

function uiPopNotify:popString(parent, str)
    -- body
    if self.notifypanel then
        self.notifypanel:removeFromParent(true)
    end

    self.notifypanel = ccui.ImageView:create("common/maopao.png", ccui.TextureResType.localType)
    local bmstr = cc.LabelBMFont:create(str, pp.fnt_common)
    local sz = self.notifypanel:getContentSize()
    bmstr:setPosition(sz.width*0.5, sz.height*0.5)
    bmstr:setScale(0.8)
    self.notifypanel:addChild(bmstr)
    
    self.notifypanel:setPosition(pp.visibleSize.width*0.5, pp.visibleSize.height*0.9)
    parent:addChild(self.notifypanel, pp.z_notify)
    
    self.notifypanel:setOpacity(0)
    local popin = cc.Spawn:create(
        cc.FadeIn:create(0.3),
        cc.MoveBy:create(0.3, cc.p(0, 20))
    )
    local popout = cc.Spawn:create(
        cc.FadeOut:create(0.3),
        cc.MoveBy:create(0.3, cc.p(0, 20))
    )

    local function removeself(sender, table)
        sender:removeFromParent(true)
        self.notifypanel = nil
    end
    local a = cc.Sequence:create(
        popin,
        cc.DelayTime:create(3),
        popout,
        cc.CallFunc:create(removeself)
    )
    self.notifypanel:runAction(a)
end

-------------------------------------------------------------
uiCreator = uiCreator or {}

function uiCreator.createAni_Zhuan(ui, image, scale, interval)
    local interval_ = interval or 2
    local scale_ = scale or 1

    local yhx,yhy = ui:getPosition()
    local foreverrot = cc.RepeatForever:create(cc.RotateBy:create(interval_, -360))
    local imageZhuan = ccui.ImageView:create(image, ccui.TextureResType.localType)
    local offset = ui:getContentSize().width*0.5
    ui:addChild(imageZhuan,1)
    imageZhuan:runAction(foreverrot)
    imageZhuan:setPosition(offset,offset)
    imageZhuan:setScale(scale_)
    return imageZhuan
end












